/* 
 * (C) 2013 Daniel Garcia <contacto {at} danigarcia.org>
 * 
 * http://danigarcia.org
 * 
 * This file is part of BlackList.
 * 
 * BlackList is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * BlackList is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with BlackList.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.danigarcia.android.blacklist;

import java.util.ArrayList;

import org.danigarcia.android.blacklist.database.BlockedPhoneListCursorAdapter;
import org.danigarcia.android.blacklist.database.DataManager;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;

public class BlockedNumbersActivity extends BaseActivity 
	implements OnClickListener, OnItemClickListener{

	private static final String TAG = BlockedNumbersActivity.class.getName();
	public static final int ACTION_PICK_CONTACT = 230382;
	public static final String PARAMETER_FILTER = "searchFilter";
	
	private ImageButton btnInsert;
	private ImageButton btnUpdate;
	private ImageButton btnDelete;
	private ImageButton btnSearch;
	
	private EditText txtContactName;
	private EditText txtContactPhone;
	
	private String filterParameter;
	private Cursor cSelect;
	
	private String selectedPhone = null;
	private int	   phoneId		 = -1;
	
	private DialogInterface.OnClickListener deleteListener = new DialogInterface.OnClickListener() {
		 
        @Override
        public void onClick(DialogInterface dialog, int which) {
        	if(dm == null)
        		return;
        	
        	int result = dm.deleteNumber(selectedPhone);
			if(result == DataManager.ERROR_ID_DOES_NOT_EXIST)
				toast(getString(R.string.msgNoExiste));
			else if(result == DataManager.ERROR)
				toast(getString(R.string.msgGenericError));
			else
				toast(getString(R.string.msgSuccess));
			loadListView(null, null);
			
			resetControls(true);
        }
    };
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_blocked_numbers);
		configureActivity();
		d(TAG, "onCreate()");
		filterParameter = getIntent().getExtras().getString(PARAMETER_FILTER);
		loadListView(filterParameter, null);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.blocked_numbers, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId()) {
	        case R.id.menuNumbersAddContact:
	        	startSelectContactAction();
	            return true;
	            
	        case R.id.menuNumbersOrder:
	        	loadListView(null, getOrderBy(DataManager.COLUMN_BLACKLIST_PHONE));
	            return true;
	            
	        case R.id.menuNumbersDeleteAll:

	        	selectedPhone = null;
	        	
	        	// Set ID to 0 to tell DataManager that we want to erase all data in the table
	        	Resources res = getResources();
	        	
	        	// Show message using the deletion message for more than one element
	        	AlertDialog alertDialog = createConfirmDialog(getString(R.string.confirm), res.getQuantityString(R.plurals.msgConfirmDelete, 2), deleteListener);
	    		alertDialog.show();
	            return true;
	        case R.id.menuNumbersBack:
	        	d(TAG, "menuCallsBack");
	        	finish();
	            return true;   
	        default:
	            return super.onOptionsItemSelected(item);
		}
	}
	
	@Override
	public void onDestroy() {
		this.dm = null;
		super.onDestroy();
	}
	
	@Override
	public void onClick(View v) {
		switch(v.getId())
		{
			case R.id.btnSearch:
			{
				loadListView(txtContactPhone.getText().toString(), null);
				break;
			}
			
			case R.id.btnInsert:
			{
				if(checkOperation())
				{
					int result = dm.insertNumber(txtContactPhone.getText().toString(), txtContactName.getText().toString());
					if(result == DataManager.ERROR_ID_EXISTS)
						toast(getString(R.string.msgNoExiste));
					else if(result == DataManager.ERROR)
						toast(getString(R.string.msgGenericError));
					else
						toast(getString(R.string.msgSuccess));
					loadListView(null, null);
					
					resetControls(true);
				}
				break;
			}
			case R.id.btnDelete:
			{
				if(!checkOperation())
					return;
				
				AlertDialog dialog = createConfirmDialog(getString(R.string.confirm), getResources().getQuantityString(R.plurals.msgConfirmDelete, 1, 1), deleteListener);
				dialog.show();
				break;
			}
			case R.id.btnUpdate:
			{
				if(!checkOperation())
					return;
				
				if(phoneId != 0)
				{
					// Checks if the phone exists
					if(dm.exists(phoneId))
					{
						int result = dm.updateNumber(phoneId, txtContactPhone.getText().toString(), txtContactName.getText().toString());
						
						if(result == DataManager.ERROR_ID_DOES_NOT_EXIST)
							toast(getString(R.string.msgNoExiste));
						else if(result == DataManager.ERROR)
							toast(getString(R.string.msgGenericError));
						else
							toast(getString(R.string.msgSuccess));
						loadListView(null, null);
						
						resetControls(true);
					}
					else
						toast(getString(R.string.msgNoExiste));
				}
			}
			default:
				break;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position, long id) 
	{
		String phone = dm.getNumberById((int)id);
		
		String name = "";
		
		Cursor c = null;
		if(phone != null)
			c = dm.getNumbers(phone);
		
		if((c != null) && (c.moveToFirst()))
			name = c.getString(c.getColumnIndex(DataManager.COLUMN_BLACKLIST_NAME));
		
		if(!c.isClosed())
			c.close();
		
		txtContactName.setText(name);
		txtContactPhone.setText(phone);
		
		this.phoneId = (int)id;
		this.selectedPhone = phone;
		
		btnDelete.setEnabled(true);
		btnUpdate.setEnabled(true);
	}
	
	@Override 
	public void onActivityResult(int reqCode, int resultCode, Intent data){ 

		super.onActivityResult(reqCode, resultCode, data);
		switch(reqCode)
		{
		   case (BlockedNumbersActivity.ACTION_PICK_CONTACT):
		   {
			   d(TAG, String.format("onActivityResult(%s, %s)", reqCode, resultCode));
			     if (resultCode == Activity.RESULT_OK)
			     {
			         Uri contactData = data.getData();
			         ArrayList<String> numberArrayList = new ArrayList<String>();
			         String contactName = null;
			         
			         @SuppressWarnings("deprecation")
					Cursor c = managedQuery(contactData, null, null, null, null);
			         d(TAG, String.format("managedQuery(contactData, null, null, null, null)"));
			         if (c.moveToFirst())
			         {
			        	 
			        	 String id = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
			        	 contactName = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
			        	 int hasPhone = Integer.parseInt(c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
			        	 
			        	 if (hasPhone >= 1) 
			        	 {
			        		 d(TAG, String.format("onActivityResult(): Contact %s (%s) has phones", contactName, id));
			        		 Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
			        				 null, 
			        				 ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,
			        				 null, 
			        				 null);

			        		 for(phones.moveToFirst(); !phones.isAfterLast(); phones.moveToNext())
			     			 {
			        			 String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
			        			 d(TAG, String.format("onActivityResult(): Adding phone %s", phoneNumber));
			     				numberArrayList.add(phoneNumber);
			     			 }
			        	 }
			        	 else
			        		 d(TAG, "onActivityResult(): Contact has no phones");
			         }
			         
			         if(contactName != null)
			        	 insertContacts(contactName, numberArrayList);
			         loadListView(null,  null);
			     }
			     break;
			   }
		}
	}
	
	@Override
	protected void configureActivity()
	{
		listView = (ListView)findViewById(R.id.lvBlackList);
		btnInsert= (ImageButton)findViewById(R.id.btnInsert);
		btnUpdate= (ImageButton)findViewById(R.id.btnUpdate);
		btnDelete= (ImageButton)findViewById(R.id.btnDelete);
		btnSearch= (ImageButton)findViewById(R.id.btnSearch);
		txtContactName= (EditText)findViewById(R.id.txtContactName);
		txtContactPhone= (EditText)findViewById(R.id.txtContactPhone);
		
		btnDelete.setEnabled(false);
		btnUpdate.setEnabled(false);
		
		btnInsert.setOnClickListener(this);
		btnUpdate.setOnClickListener(this);
		btnDelete.setOnClickListener(this);
		btnSearch.setOnClickListener(this);
		
		listView.setOnItemClickListener(this);
		
		dm = new DataManager(this, DataManager.DB_NAME, null, DataManager.DB_VERSION);
		
	}

	@Override
	protected CursorAdapter getAdapter(String filter, String orderBy) {
		cSelect = dm.getNumbers(filter, orderBy);
		cursorAdapter = new BlockedPhoneListCursorAdapter(this, cSelect);
		return cursorAdapter;
	}
		
	private void resetControls(boolean forInsert)
	{
		txtContactName.setText("");
		txtContactPhone.setText("");
		txtContactName.requestFocus();
		
		btnUpdate.setEnabled(!forInsert);
		btnDelete.setEnabled(!forInsert);
		
		phoneId = 0;
		selectedPhone = null;
	}
	
	private boolean checkOperation()
	{
		if(txtContactName.getText().toString().length() == 0)
			return false;
		if(txtContactPhone.getText().toString().length() == 0)
			return false;
		
		return true;
	}
	
	private void deleteNumber()
	{
		int result = dm.deleteNumber(selectedPhone);
		if(result == DataManager.ERROR_ID_DOES_NOT_EXIST)
			toast(getString(R.string.msgNoExiste));
		else if(result == DataManager.ERROR)
			toast(getString(R.string.msgGenericError));
		else
			toast(getString(R.string.msgSuccess));
		loadListView(null, null);
		
		resetControls(true);
	}
	
	private void startSelectContactAction()
	{
		Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
        startActivityForResult(intent, ACTION_PICK_CONTACT);
	}

	private void insertContacts(String name, ArrayList<String> numbers)
	{
		d(TAG,String.format("insertContacts(%s, %s)", name, numbers.size()));
		int id = 1;
		for(String number : numbers)
		{
			if(!dm.exists(number))
				dm.insertNumber(number.replaceAll("\\s+",""), id > 1 ? String.format("%s (%s)",  name, id) : name);
			id++;
		}
	}
}
